package at.fhv.components.roi;

import java.awt.Rectangle;

import javax.media.jai.PlanarImage;

import at.fhv.framework.CommonImageProcessingHelper;
import at.fhv.framework.events.ImageEvent;
import at.fhv.framework.listeners.ImageProcessingListener;
import at.fhv.framework.listeners.RefireListener;

/**
 * The ROIFilter class.
 * 
 * @author Michael Sieber
 */
public class ROIFilter implements ImageProcessingListener, RefireListener
{
	private CommonImageProcessingHelper	_helper;
	private PlanarImage					_image;
	private int							_height;
	private int							_width;
	private int							_x;
	private int							_y;
	private int							MIN_HEIGHT	= 1;
	private int							MIN_WIDTH	= 1;

	public ROIFilter()
	{
		_height = 50;
		_width = 50;
		_x = 0;
		_y = 0;
		_helper = new CommonImageProcessingHelper(this);
	}

	/*
	 * {@inheritDoc}
	 */
	@Override
	public void refire() {
		_helper.fireImageProcessingEvent(new ImageEvent(this, _image));
	}

	/*
	 * {@inheritDoc}
	 */
	@Override
	public void imageChanged(ImageEvent event) {
		execute(event.getImage());
		_image = event.getImage();
	}

	/**
	 * Execute roi
	 * 
	 * @param image
	 */
	private void execute(PlanarImage img) {
		if (img != null)
		{
			Rectangle rectangle = new Rectangle(_x, _y, _width, _height);
			img = PlanarImage.wrapRenderedImage(img.getAsBufferedImage(rectangle,
					img.getColorModel()));
			_helper.fireImageProcessingEvent(new ImageEvent(this, img));
		}
	}

	/*
	 * {@inheritDoc}
	 */
	@Override
	public void addRefireListener(RefireListener listener) {
		_helper.addRefireListener(listener);
	}

	/*
	 * {@inheritDoc}
	 */
	@Override
	public void removeRefireListener(RefireListener listener) {
		_helper.removeRefireListener(listener);
	}

	/**
	 * Add an image change listener
	 * 
	 * @param listener
	 *            The image change listener to add
	 */
	public void addImageChangeListener(ImageProcessingListener listener) {
		_helper.addImageProcessingListener(listener);

		// force all previous beans to refire their event
		_helper.fireRefireEvent();
	}

	/**
	 * Remove an image change listener
	 * 
	 * @param listener
	 *            The image change listener to remove
	 */
	public void removeImageChangeListener(ImageProcessingListener listener) {
		_helper.removeImageProcessingListener(listener);
	}

	/**
	 * @return The height
	 */
	public int getHeight() {
		return _height;
	}

	/**
	 * @param height
	 *            The height to set
	 */
	public void setHeight(int height) {
		_helper.fireRefireEvent();
		_height = height;

		if (_image != null)
		{
			int maxPossibleHeight = _image.getHeight() - _y;

			if (_height > maxPossibleHeight)
			{
				_height = maxPossibleHeight;
			}
			if (_height < 0)
			{
				_height = MIN_HEIGHT;
			}
		}

		execute(_image);
	}

	/**
	 * @return The width
	 */
	public int getWidth() {
		return _width;
	}

	/**
	 * @param width
	 *            The width to set
	 */
	public void setWidth(int width) {
		_helper.fireRefireEvent();
		_width = width;

		if (_image != null)
		{
			int maxPossibleWidth = _image.getWidth() - _x;

			if (_width > maxPossibleWidth)
			{
				_width = maxPossibleWidth;
			}
			if (_width < 0)
			{
				_width = MIN_WIDTH;
			}
		}

		execute(_image);
	}

	/**
	 * @return The x
	 */
	public int getX() {
		return _x;
	}

	/**
	 * @param x
	 *            The x to set
	 */
	public void setX(int x) {
		_helper.fireRefireEvent();
		_x = x;

		if (_image != null)
		{
			if (_x > _image.getWidth())
			{
				_x = _image.getWidth();
			}
			if (_x < 0)
			{
				x = 0;
			}
		}

		execute(_image);
	}

	/**
	 * @return The y
	 */
	public int getY() {
		return _y;
	}

	/**
	 * @param y
	 *            The y to set
	 */
	public void setY(int y) {
		_helper.fireRefireEvent();
		_y = y;

		if (_image != null)
		{
			if (_y > _image.getHeight())
			{
				_y = _image.getHeight();
			}
			if (_y < 0)
			{
				_y = 0;
			}
		}

		execute(_image);
	}
}